local skynet = require "skynet"
local msg_center = require "common.msg_center"
local proto_manager = require "common.proto_manager"
local MessageType = require "common.message_type"
local time_manager = require "common.time_manager"
local match_manager = require "match.match_manager"
local service_helper = require "common.service_helper"

local function onBeginMatchReq(data)

    local ok = false
    local result = proto_manager.errcode("ErrorCode_Successed")

    local matchInfo = match_manager.getMatchByOpenID(data.open_id)
    if matchInfo then
        ok = match_manager.online(data)
        if not ok then
            result = proto_manager.errcode("ErrorCode_SystemError")
            skynet.error("match online faild! open_id:" .. data.open_id .. " matchid:" .. tostring(matchInfo:getID()))
        end
    else
        ok,matchInfo = match_manager.enter_match(data)
        if not ok then
            result = proto_manager.errcode("ErrorCode_SystemError")
            skynet.error("enter_match faild! open_id:" .. data.open_id)
        end
    end

    local resp = {
        open_id = data.open_id,
        result = result,
        match_id = matchInfo:getID(),
        players = matchInfo:getPlayerInfos(),
    }
    service_helper.send2Agent(MessageType.MessageId_BeginMatchResp,resp)

    if ok and matchInfo:isStarted() then
        local data = {
            open_ids = {data.open_id},
            message_id = "MessageId_NotifyGameStart",
            message_type = "MessageNotifyGameStart",
            msg = matchInfo:getGameStartInfo(data.open_id),
        }
        service_helper.send2Agent(MessageType.Forward2Client,data)
    end

end
msg_center.setDefaultMessageHandler(MessageType.MessageId_BeginMatchReq,onBeginMatchReq)

local function onCancelMatchReq(data)

    local result = proto_manager.errcode("ErrorCode_Successed")

    local matchInfo = match_manager.getMatchByOpenID(data.open_id)
    if matchInfo then
        if matchInfo:canLeave() then
            if not match_manager.player_leave(data.open_id) then
                result = proto_manager.errcode("ErrorCode_SystemError")
                skynet.error("cancel match leave faild! open_id:" .. data.open_id .. " matchid:" .. tostring(matchInfo:getID()))
            end
        else
            result = proto_manager.errcode("ErrorCode_MatchCannotCanceled")
        end
    else
        result = proto_manager.errcode("ErrorCode_NotFindMatch")
    end

    local resp = {
        open_id = data.open_id,
        result = result,
        match_id = data.match_id,
    }
    service_helper.send2Agent(MessageType.MessageId_CancelMatchResp,resp)

end
msg_center.setDefaultMessageHandler(MessageType.MessageId_CancelMatchReq,onCancelMatchReq)

local function onFightReadyReq(data)

    local result = proto_manager.errcode("ErrorCode_Successed")

    local matchInfo = match_manager.getMatchByOpenID(data.open_id)
    if matchInfo then
        if matchInfo:isInPrepare() then
            if not matchInfo:setPlayerReady(data.open_id,data.state) then
                result = proto_manager.errcode("ErrorCode_SystemError")
                skynet.error("fight read req setPlayerReady faild! open_id:" .. data.open_id
                        .. " matchid:" .. tostring(matchInfo:getID()) .. " state:" .. tostring(data.state))
            end
        else
            result = proto_manager.errcode("ErrorCode_MatchNotInPrepareStage")
        end
    else
        result = proto_manager.errcode("ErrorCode_NotFindMatch")
    end

    local resp = {
        open_id = data.open_id,
        result = result,
        match_id = data.match_id,
        state = data.state,
    }
    service_helper.send2Agent(MessageType.MessageId_FightReadyResp,resp)

    if proto_manager.errcode("ErrorCode_Successed") == result then

        if matchInfo:checkAllReady() then

            local players = {}

            matchInfo:foreachPlayers(function(player)
                local v = {
                    open_id = player.open_id,
                    index = player.index,
                }
                table.insert(players,v)
            end)

            local info = {
                match_id = matchInfo:getID(),
                players = players,
            }

            service_helper.send2Race(MessageType.RegisterRaceRoomReq,info)

        end

    end

end
msg_center.setDefaultMessageHandler(MessageType.MessageId_FightReadyReq,onFightReadyReq)

local function onRegisterRaceRoomResp(data)

    if data.result ~= proto_manager.errcode("ErrorCode_Successed") then
        match_manager.onMatchRaceException(data.match_id,data.result)
        skynet.error("onRegisterRaceRoomResp faild! result:" .. tostring(data.result))
        return
    end

    local matchInfo = match_manager.getMatchedByID(data.match_id)
    if not matchInfo then
        match_manager.onMatchRaceException(data.match_id,proto_manager.errcode("ErrorCode_NotFindMatch"))
        skynet.error("onRegisterRaceRoomResp faild! not find match id:" .. tostring(data.match_id))
        return
    end

    if not matchInfo:onGameStart(data.ip,data.port,data.players) then
        match_manager.onMatchRaceException(data.match_id,proto_manager.errcode("ErrorCode_SystemError"))
        skynet.error("onGameStart faild! match id:" .. tostring(data.match_id))
    end

end
msg_center.setDefaultMessageHandler(MessageType.RegisterRaceRoomResp,onRegisterRaceRoomResp)

local function onEndGameReq(data)

    local result = proto_manager.ErrorCode_Successed

    local matchInfo = match_manager.getMatchByOpenID(data.open_id)
    if matchInfo then
        if matchInfo:canEnd() then
            if not matchInfo:onPlayerRequestEnd(data.open_id,data) then
                result = proto_manager.errcode("ErrorCode_SystemError")
                skynet.error("onPlayerRequestEnd failed! open_id:" .. data.open_id .. " matchid:" .. tostring(matchInfo:getID()))
            end
        else
            result = proto_manager.errcode("ErrorCode_MatchNotInCanSettlementStage")
        end
    else
        result = proto_manager.errcode("ErrorCode_NotFindMatch")
    end

    if result ~= proto_manager.ErrorCode_Successed then
        local resp = {
            open_id = data.open_id,
            result = result,
            room_id = data.room_id,
            players = data.players,
        }
        service_helper.send2Agent(MessageType.MessageId_EndGameResp,resp)
    end

end
msg_center.setDefaultMessageHandler(MessageType.MessageId_EndGameReq,onEndGameReq)

local function onRaceRoomEnd(data)

    if data.result ~= proto_manager.errcode("ErrorCode_Successed") then
        match_manager.onMatchRaceException(data.room_id,data.result)
        skynet.error("onRaceRoomEnd result:" .. tostring(data.result))
        return
    end

    local matchInfo = match_manager.getMatchedByID(data.room_id)
    if matchInfo then
        match_manager.end_match(data.room_id)
    end

end
msg_center.setDefaultMessageHandler(MessageType.RaceRoomEnd,onRaceRoomEnd)